package com.atjava.webspider.thread;

import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Date;
import java.util.List;
import java.util.StringTokenizer;

import org.apache.commons.lang.StringUtils;

import com.atjava.webspider.consts.Const;
import com.atjava.webspider.gui.SpiderMainGui;
import com.atjava.webspider.html.DefaultLinkParser;
import com.atjava.webspider.html.LinkParser;
import com.atjava.webspider.logic.CommonLogic;
import com.atjava.webspider.logic.ConfigLogic;
import com.atjava.webspider.logic.OutputLogic;
import com.atjava.webspider.logic.TaskLogic;
import com.atjava.webspider.model.Output;
import com.atjava.webspider.model.Page;
import com.atjava.webspider.model.Site;
import com.atjava.webspider.model.Task;
import com.atjava.webspider.thread.infs.NamedTask;
import com.atjava.webspider.util.HttpUtil;
import com.atjava.webspider.util.LogUtil;

public class SpiderTask implements NamedTask {
	
	private enum TaskState{RUNNING,STOPPED,PAUSED}

	private Task task;
	
	/** 0:运行  1:停止 2：暂停*/
	private TaskState flag ;

	private OutputLogic outLogic;
	private TaskLogic taskLogic;
	private Site site;

	public SpiderTask(Task task) {
		this.task = task;
		this.outLogic = new OutputLogic(task);
		this.taskLogic = new TaskLogic();
		List<Site> sites = ConfigLogic.getSiteConfig().getSites();
		this.site = (Site)CommonLogic.getByName(sites,task.getSite());
	}
	
	public Object getName() {
		return task.getId();
	}

	public void run() {
		SpiderMainGui mainGui = SpiderMainGui.getInstance();
		//开始监听
		mainGui.getTaskListener().goon();
		// 任务开始时间　
		task.setStartTime(new Date());
		task.setState(Const.TASK_STATE_DOWNING);
		task.setDataNum(0);
		mainGui.getTaskListener().updateTaskRow(task);
		try {
			// 读取已采集的ＵＲＬ列表
			// File urlListFile = new File(Const.TASK_HOME + "/" + task.getId()
			// + "/urls.ini");
			// if(urlListFile.exists()){
			// if(urlBuffer.length() != 0)
			// urlBuffer = new StringBuffer();
			// urlBuffer.append(fsu.readText(urlListFile.getAbsolutePath()));
			// }
			URL taskUrl = new URL(task.getUrl());
			process(taskUrl);
		} catch (Exception e) {
			e.printStackTrace();
		}
		mainGui.getTaskListener().updateTaskRow(task);
		task.setState(Const.TASK_STATE_FINISHED);
		task.getUrlBuffer().delete(0, task.getUrlBuffer().length());
		taskLogic.updateTaskFile(task);
		LogUtil.log("==========Done========");
		//停止监听
		mainGui.getTaskListener().pause();
	}
	
	/*
	 * public void outputUrlList()throws Exception{ File listCfgFile = new
	 * File(Const.TASK_HOME + "/" + task.getId() + "/urls.ini"); FileSystemUtil
	 * fsu = new FileSystemUtil(); fsu.writeText(urlBuffer.toString(),
	 * listCfgFile); }
	 */

	public boolean isProcessd(String url) {
		StringTokenizer st = new StringTokenizer(task.getUrlBuffer().toString());
		while (st.hasMoreTokens()) {
			if (url.equals(st.nextToken()))
				return true;
		}
		return false;
	}
	
	public void process(URL url) throws Exception {
		// 最大深度
		int maxdepth = this.task.getMaxDepth();
		//System.out.println("cache:" + task.getUrlBuffer().toString().getBytes().length);
		try {
			// 下载资源（文本、图片、Flash）
			Output out = outLogic.getOutput(url.toString());
			if (out != null) {
				
				LogUtil.log("正在打开 : " + url.toString());
				HttpURLConnection connection = HttpUtil.getValidConnection(url);
				if(connection == null)
					return ;
				String content = HttpUtil.getTextResource(connection, site.getCharset());
				//断开连接
				connection.disconnect();
				if (content == null || content.length() == 0)
					return ;
				
				//访问URL记录
				task.getUrlBuffer().append(url.toString());
				task.getUrlBuffer().append("\r\n");
				
				outLogic.output(url, content, out);
				Page pg = (Page)CommonLogic.getByName(site.getPages(),out.getPage());
				//如果输出级别大于最大深度则不进行向下采集
				if (pg.getLevel() >= maxdepth) 
					return ;
				// 获取页面link
				LinkParser parser = DefaultLinkParser.getInstance();
				List<String> linkTags = parser.parseLink(content);
				// 循环一个页面上所有连接
				for (int i = 0; i < linkTags.size(); i++) {
					//停止
					if(flag == TaskState.STOPPED)
						break ;
					//暂停
					if(flag == TaskState.PAUSED){
						synchronized (task) {
							task.wait();
						}
					}
					String absLinkUrl = HttpUtil.getAbsoluteUrl(url.toString(), linkTags.get(i));
					// 如果获取绝对路径失败则返回
					if (StringUtils.isBlank(absLinkUrl))
						continue;
					// 如果列表存在该地址则返回
					if (isProcessd(absLinkUrl))
						continue;
					// 如果不属于该网站则返回
					if (!HttpUtil.getDomain(absLinkUrl).equals(HttpUtil.getDomain(task.getUrl())))
						continue;
					// 如果找不到对应的输出，说明不对该URL进行采集，则返回
					if(outLogic.getOutput(absLinkUrl) == null)
						continue;
					process(new URL(absLinkUrl));
				}
			}
				
		} catch (Exception e) {
			e.printStackTrace();
			throw e;
		}
	}

	public void pause() {
		flag = TaskState.PAUSED;
		task.setState(Const.TASK_STATE_PAUSED);
	}

	public void goon() {
		flag = TaskState.RUNNING;
		synchronized (task) {
			task.notify();
		}
		task.setState(Const.TASK_STATE_DOWNING);
	}

	public void stop() {
		flag = TaskState.STOPPED;
		synchronized (task) {
			task.notify();
		}
		task.setState(Const.TASK_STATE_STOP);
		taskLogic.updateTaskFile(task);
	}
	
	public void waitting() {
		task.setState(Const.TASK_STATE_WATTING);
	}

}